﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
using System.Security;
using System.Runtime.Serialization;
using System.Globalization;

namespace FluentMef
{
    internal static class Assumes
{
    // Methods
    [DebuggerStepThrough]
    internal static void Fail([Localizable(false)] string message)
    {
        throw new InternalErrorException(message);
    }

    [DebuggerStepThrough]
    internal static void IsFalse(bool condition)
    {
        if (condition)
        {
            Fail(null);
        }
    }

    [DebuggerStepThrough]
    internal static void IsTrue(bool condition)
    {
        if (!condition)
        {
            Fail(null);
        }
    }

    [DebuggerStepThrough]
    internal static void IsTrue(bool condition, [Localizable(false)] string message)
    {
        if (!condition)
        {
            Fail(message);
        }
    }

    [DebuggerStepThrough]
    internal static void NotNull<T>(T value) where T: class
    {
        IsTrue(value != null);
    }

    [DebuggerStepThrough]
    internal static void NotNull<T1, T2>(T1 value1, T2 value2) where T1: class where T2: class
    {
        NotNull<T1>(value1);
        NotNull<T2>(value2);
    }

    [DebuggerStepThrough]
    internal static void NotNull<T1, T2, T3>(T1 value1, T2 value2, T3 value3) where T1: class where T2: class where T3: class
    {
        NotNull<T1>(value1);
        NotNull<T2>(value2);
        NotNull<T3>(value3);
    }

    [DebuggerStepThrough]
    internal static void NotNullOrEmpty(string value)
    {
        NotNull<string>(value);
        IsTrue(value.Length > 0);
    }

    [DebuggerStepThrough]
    internal static T NotReachable<T>()
    {
        throw new InternalErrorException("Code path should never be reached!");
    }

    [DebuggerStepThrough]
    internal static void Null<T>(T value) where T: class
    {
        IsTrue(value == null);
    }

    // Nested Types
    [Serializable]
    private class InternalErrorException : Exception
    {
        // Methods
        public InternalErrorException(string message) : base(message)
        {
        }

        [SecuritySafeCritical]
        protected InternalErrorException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
    }
}

}
